package org.finegold.core.netty.core.codc;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.finegold.core.netty.handler.ServerHandler;
import org.finegold.core.netty.props.ServerProperties;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@Slf4j
public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {

    private final ServerProperties serverProperties;

    public NettyServerInitializer(ServerProperties serverProperties) {
        this.serverProperties = serverProperties;
    }

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        //获取通道链
        ChannelPipeline pipeline = socketChannel.pipeline();
        //组装链
        pipeline.addLast(new IdleStateHandler(serverProperties.getReadTime(),serverProperties.getWriteTime(),serverProperties.getReadAndWriteTime()))
                .addLast(new RequestDecoder())
                .addLast(new ResponseEncoder())
                .addLast(resolveHandler(serverProperties.getChannelHandlers()));
    }

    /**
     * 解析处理器
     * @param channelHandlers 需要被实例化的通道处理器
     * @return 通道处理器数组
     * @throws IllegalAccessException 非法访问异常
     * @throws InstantiationException 实例化异常
     */
    private ChannelHandler[] resolveHandler(List<Class<? extends ChannelHandler>> channelHandlers) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        int size = channelHandlers.size();
        // 警告检查
        if(size == 1 && (channelHandlers.get(0).isAssignableFrom(ServerHandler.class))){
            log.warn("=================>请自定义ChannelHandler并在配置文件中配置!<===================");
        }
        //创建返回的处理器数组
        ChannelHandler[] chs = new ChannelHandler[size];
        for (int i = 0; i < size; i++) {
            Class<? extends ChannelHandler> cls = channelHandlers.get(i);
            //获取无参构造方法
            Constructor<? extends ChannelHandler> constructor = cls.getConstructor();
            //无参实例化
            chs[i] = constructor.newInstance();
        }
        return chs;
    }
}
